package com.example.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;

@Aspect
@Component
public class UserAspect {
    public UserAspect() {
        System.out.println("UserAspect() constructor invoke ....");
    }


 /*   @Before("execution(public  * com.example.service.IUserService.addUser())")
    public void beforeAddUserAdvice(){
        System.out.println("beforeAddUserAdvice() invoke ...");
    }*/


/*    @Pointcut(value = "execution(* com.example.service.IUserService.addUser())")
    public void addUserPointCut(){
    }

    @Before(value = "addUserPointCut()")
    public void beforeAddUserAdvice(){
        System.out.println("beforeAddUserAdvice() invoke ...");
    }
    */

/*
    @Pointcut(value = "execution(* com.example.service..*.*(..))")
    public void userServicePointCut(){

    }

    @Before(value = "userServicePointCut()")
    public void beforeUserAdvice(){
        System.out.println("beforeUserAdvice() invoke ...");
    }
*/

/*    @Pointcut(value = "execution(* com.example.service..*.*(..))&&args(java.lang.Integer)")
    public void queryUserPonintCut(){

    }

    @Before(value = "queryUserPonintCut()")
    public void beforeQueryUserAdvice(){
        System.out.println("beforeQueryUserAdvice() invoke ...");
    }*/

  /*  @Pointcut(value = "bean(userService)&& execution(public * *.*(..))")
    public void userServicePointCut() {

    }

    @Before(value = "userServicePointCut()")
    public void beforeUserAdvice() {
        System.out.println("beforeUserAdvice() invoke ...");
    }*/
/*
//    proxyTargetClass = false
//    @Pointcut(value = "this(com.example.service.UserService)"

  //    proxyTargetClass = false
    @Pointcut(value = "this(com.example.service.IUserService)")

//    proxyTargetClass = true
//    @Pointcut(value = "this(com.example.service.UserService)")
    public void thisServicePointCut() {

    }

    @Before(value = "thisServicePointCut()")
    public void beforeUserAdvice() {
        System.out.println("this pointcut invoke ...");
    }*/

/*
//    @Pointcut(value = "target(com.example.service.UserService)")
   @Pointcut(value = "this(com.example.service.IUserService)")
    public void targetServicePointCut() {

    }

    @Before(value = "targetServicePointCut()")
    public void beforeUserAdvice() {
        System.out.println("target pointcut invoke ...");
    }*/


    @Pointcut(value = "execution(* com.example.service.IUserService.queryUser(..))")
    public void addUserPointCut(){
    }

    @Around(value = "addUserPointCut()")
    public Object  aroundAddUserAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("aroundAddUserAdvice() invoke ...");
        AtomicInteger i = new AtomicInteger(1);
        Arrays.asList(proceedingJoinPoint.getArgs()).stream().forEach(s->{
            System.out.println("args["+(i.getAndIncrement())+"]"+String.valueOf(s));
        });
        //重置参数
        Object ret = proceedingJoinPoint.proceed(new Object[]{2});
        System.out.println("ret = " + ret);
        return  ret;
    }

}
